using System;
using Oracle.ManagedDataAccess.Client;
using OracleInternal.Common;

namespace OracleInternal.BulkCopy
{
	internal class BulkCopySourceOracleDataReader : BulkCopySourceDotNetTypes
	{
		internal OracleDataReader m_dataSource;

		internal BulkCopySourceOracleDataReader(OracleDataReader reader, OracleBulkCopy bulkCopy, int requestedBatchSize)
			: base(bulkCopy, requestedBatchSize)
		{
			m_dataSource = reader;
		}

		public override int GetColumnCount()
		{
			return m_dataSource.FieldCount;
		}

		public override int GetColumnOrdinal(string columnName)
		{
			return m_dataSource.GetOrdinal(columnName);
		}

		public override Type GetSrcColumnType(int columnIndex)
		{
			return m_dataSource.GetFieldType(columnIndex);
		}

		public override int GetBatchSize()
		{
			if (m_requestedBatchSize > 0)
			{
				return m_requestedBatchSize;
			}
			return 10000;
		}

		private int PopulateOneRow(OracleBulkCopyColumnMappingCollection internalColumnMappings)
		{
			if (!m_dataSource.Read())
			{
				return 0;
			}
			for (int i = 0; i < internalColumnMappings.Count; i++)
			{
				int sourceOrdinal = internalColumnMappings[i].SourceOrdinal;
				switch (m_dataSource.m_readerImpl.m_accessors[sourceOrdinal].m_internalType)
				{
				case OraType.ORA_OCIBLobLocator:
					m_columns[i].Value = m_dataSource.GetOracleBinary(sourceOrdinal);
					break;
				case OraType.ORA_OCICLobLocator:
					m_columns[i].Value = m_dataSource.GetOracleString(sourceOrdinal);
					break;
				default:
					m_columns[i].Value = m_dataSource.GetOracleValue(sourceOrdinal);
					break;
				}
			}
			return 1;
		}

		protected int PopulateArrayRows(OracleBulkCopyColumnMappingCollection internalColumnMappings, int numOfRows)
		{
			foreach (OracleParameter column in m_columns)
			{
				column.Value = new object[numOfRows];
			}
			int i;
			for (i = 0; i < numOfRows; i++)
			{
				if (!m_dataSource.Read())
				{
					break;
				}
				for (int j = 0; j < internalColumnMappings.Count; j++)
				{
					object[] array = (object[])m_columns[j].Value;
					int sourceOrdinal = internalColumnMappings[j].SourceOrdinal;
					switch (m_dataSource.m_readerImpl.m_accessors[sourceOrdinal].m_internalType)
					{
					case OraType.ORA_OCIBLobLocator:
						array[i] = m_dataSource.GetOracleBinary(sourceOrdinal);
						break;
					case OraType.ORA_OCICLobLocator:
						array[i] = m_dataSource.GetOracleString(sourceOrdinal);
						break;
					default:
						array[i] = m_dataSource.GetOracleValue(sourceOrdinal);
						break;
					}
				}
			}
			return i;
		}

		public override int PopulateRows(OracleBulkCopyColumnMappingCollection internalColumnMappings, int numOfRow)
		{
			if (numOfRow == 1)
			{
				return PopulateOneRow(internalColumnMappings);
			}
			return PopulateArrayRows(internalColumnMappings, numOfRow);
		}
	}
}
